﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using CommonFramework.Serialize.BytesArray;

namespace Net.Channel
{
    /// <summary>
    /// 封装网络传输接收的协议实现
    /// </summary>
    public abstract class NetChannel
    {
        public abstract ProtocolType Protocol { get; }
        public readonly NetSession Session;

        public NetChannel(NetSession session)
        {
            this.Session = session;
        }

        public virtual bool IsConnected()
        {
            return !(Session?.Socket == null || Session.Socket.Connected == false);
        }
        public virtual bool IsConnecting()
        {
            if (!IsClosed() && !IsConnected())
                return true;
            else
                return false;
        }
        public virtual bool IsClosed()
        {
            return Session?.Socket == null;
        }

        /// <summary>
        /// 写入数据缓冲区
        /// </summary>
        protected Queue<BytesBuffer> _sendBuffer = new Queue<BytesBuffer>();
        /// <summary>
        /// 接收数据缓冲区
        /// </summary>
        protected BytesBuffer _recvBuffer = new BytesBuffer();

        public virtual void Send(byte[] bytes, int offset, int length)
        {
            BytesBuffer sendBytes = new BytesBuffer();
            sendBytes.GetWriter().WriteBytes(bytes, offset, length);
            Send(sendBytes);
        }

        public virtual void Send(NetPacket packet)
        {
            //对消息包进行序列化
            BytesBuffer sendBytes = NetUtil.GetBytesFromPacket(packet);
            Send(sendBytes);
        }
        public abstract void Send(BytesBuffer sendBytes);

        public abstract void Receive(byte[] bytes, int offset, int length);
        public abstract void Receive(NetPacket packet);

        public virtual void Close()
        {
        }
        public virtual void Clear()
        {
            _recvBuffer = new BytesBuffer();
            lock (_sendBuffer)
            {
                _sendBuffer = new Queue<BytesBuffer>();
            }
        }
    }
}